#include "GLES2GpuProgramManager.h"
#include "GLES2GpuProgram.h"
#include "LogManager.h"

namespace PVM
{
	GLES2GpuProgramManager::GLES2GpuProgramManager()
	{
		ResourceGroupManager::getSingleton()._registerResourceManager(mResourceType, this);
	}
	
	GLES2GpuProgramManager::~GLES2GpuProgramManager()
	{
		ResourceGroupManager::getSingleton()._unregisterResourceManager(mResourceType);
	}
	
	bool GLES2GpuProgramManager::registerProgramFactory(const std::string& syntaxCode,
														CreateGpuProgramCallback createFn)
	{
		return mProgramMap.insert(ProgramMap::value_type(syntaxCode, createFn)).second;
	}
	
	bool GLES2GpuProgramManager::unregisterProgramFactory(const std::string& syntaxCode)
	{
		return mProgramMap.erase(syntaxCode) != 0;
	}
	
	Resource* GLES2GpuProgramManager::createImpl(const std::string& name,
												 ResourceHandle handle,
												 const std::string& group, bool isManual,
												 ManualResourceLoader* loader,
												 const NameValuePairList* params)
	{
		NameValuePairList::const_iterator paramSyntax, paramType;
		
		if (!params || (paramsSyntax = params->find("syntax")) == params.end() ||
			(paramType = params->find("type")) == params->end())
		{
			PVM_EXCEPT("You must supply 'syntax' and 'type' parameters",
					   "GLES2GpuProgramManager::createImpl");
		}
		
		ProgramMap::const_iterator iter = mProgramMap.find(paramSyntax->second);
		if (iter == mProgramMap.end())
		{
			return new GLES2GpuProgram(this, name, handle, group, isManual, loader);
		}
		
		GpuProgramType gpt;
		if (paramType->second == "vertex_program")
		{
			gpt = GPT_VERTEX_PROGRAM;
		}
		else
		{
			gpt = GPT_FRAGMENT_PROGRAM;
		}
		
		return (iter->second)(this, name, handle, group, isManual,
							  loader, gpt, paramSyntax->second);
	}
	
	Resource* GLES2GpuProgramManager::createImpl(const std::string& name, 
												 ResourceHandle handle,
												 const std::string& group, bool isManual,
												 ManualResourceLoader* loader,
												 GpuProgramType gptype,
												 const std::string& syntaxCode)
	{
		ProgramMap::const_iterator iter = mProgramMap.find(syntaxCode);
		if (iter == mProgramMap.end())
		{
			return new GLES2GpuProgram(this, name, handle, group, isManual, loader);
		}
		
		return (iter->second)(this, name, handle, group, isManual, loader, gptype, syntaxCode);
	}
}
